package com.seanzx.server.handler;

import com.seanzx.common.NetSerializer;
import com.seanzx.common.Result;
import com.seanzx.common.ResultCode;
import com.seanzx.resolver.ResolverChain;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.List;

public class ConnectionHandler implements Runnable {
    private final Socket socket;
    private final ResolverChain resolverChain = ResolverChain.get();

    public ConnectionHandler(Socket socket) {
        this.socket = socket;
    }


    @Override
    public void run() {
        try (BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
             PrintWriter pw = new PrintWriter(socket.getOutputStream())) {
            // FIXME: comment contains ;
            while (true) {
                String sql = br.readLine();

                long start = System.currentTimeMillis();
                System.out.println("message from client[" + socket.getInetAddress().getHostAddress() + "]:" + sql);
                Result result = resolverChain.tryTranslate(sql);
                long executeTime = System.currentTimeMillis() - start;

                NetSerializer.NetRes netRes = new NetSerializer.NetRes();
                netRes.setExecuteTime((int)executeTime);
                netRes.setResultCode(result.getResultCode().getCode());
                netRes.setResultMessage(result.getResultCode().getMessage());
                if (ResultCode.SUCCESS.equals(result.getResultCode())) {
                    if (result.getData() == null) {
                        netRes.setType(NetSerializer.TYPE_SUCCESS);
                    } else if (result.getData() instanceof Integer) {
                        netRes.setRows((Integer)result.getData());
                        netRes.setType(NetSerializer.TYPE_ROWS);
                    } else {
                        netRes.setResults((List<List<String>>) result.getData());
                        netRes.setType(NetSerializer.TYPE_DATA);
                    }
                }

                pw.write(NetSerializer.serialize(netRes));
                pw.flush();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
